using ColorFillGame.Domain.Exceptions;
using ColorFillGame.Domain.Repositories;
using ColorFillGame.Domain.Services;
using MediatR;

namespace ColorFillGame.Application.Queries.Game;

public class GetGameQueryHandler : IRequestHandler<GetGameQuery, GameDto>
{
    private readonly IGameRepository _gameRepository;
    private readonly IPlayerRepository _playerRepository;
    private readonly IGameService _gameService;

    public GetGameQueryHandler(
        IGameRepository gameRepository,
        IPlayerRepository playerRepository,
        IGameService gameService)
    {
        _gameRepository = gameRepository;
        _playerRepository = playerRepository;
        _gameService = gameService;
    }

    public async Task<GameDto> Handle(GetGameQuery request, CancellationToken cancellationToken)
    {
        // 获取游戏
        var game = await _gameRepository.GetByIdAsync(request.GameId);
        if (game == null)
            throw new GameNotFoundException(request.GameId);

        // 获取游戏中的所有玩家
        var players = await _playerRepository.GetByGameIdAsync(request.GameId);
        
        // 计算玩家分数
        var scores = new Dictionary<Guid, int>();
        foreach (var player in players)
        {
            if (player.Color != null)
            {
                var filledCells = game.Grid.GetFilledCellsByColor(player.Color);
                scores[player.Id] = filledCells.Count;
            }
            else
            {
                scores[player.Id] = 0;
            }
        }

        // 转换为DTO
        var gameDto = new GameDto
        {
            Id = game.Id,
            Name = game.Name,
            GridSize = game.GridSize,
            MaxPlayers = game.MaxPlayers,
            CurrentPlayers = players.Count(),
            Status = game.Status,
            StatusName = game.Status.ToString(), // 添加字符串形式的状态
            WinnerId = game.WinnerId,
            Players = players
                .Select(player => new PlayerDto
                {
                    Id = player.Id,
                    Name = player.Name,
                    ColorCode = player.Color?.Code ?? string.Empty,
                    Score = scores.TryGetValue(player.Id, out var score) ? score : 0,
                    Ready = player.Ready
                })
                .ToList()
        };

        return gameDto;
    }
}